package cn.monkey.io.transport.netty;

import cn.monkey.io.transport.core.Exchange;
import cn.monkey.io.transport.core.ExchangeContext;
import io.netty.channel.Channel;
import reactor.core.publisher.Mono;

import java.net.SocketAddress;

public class DefaultChannelExchange implements ChannelExchange {
    private final String id;
    protected final ChannelConnection connection;
    protected final Channel channel;
    protected final ExchangeContext exchangeContext;

    public DefaultChannelExchange(String id,
                                  Channel channel) {
        this.id = id;
        this.channel = channel;
        this.connection = this.newConnection(channel);
        this.exchangeContext = new NettyAttributeContext(channel);
    }

    @Override
    public Channel channel() {
        return this.channel;
    }

    protected ChannelConnection newConnection(Channel channel) {
        return new DefaultChannelConnection(channel).bind();
    }

    @Override
    public String id() {
        return this.id;
    }

    @Override
    public ExchangeContext context() {
        return this.exchangeContext;
    }

    @Override
    public ChannelInbound inbound() {
        return this.connection;
    }

    @Override
    public ChannelOutbound outbound() {
        return this.connection;
    }

    @Override
    public Mono<Void> close() {
        return this.connection.close();
    }

    @Override
    public boolean isActive() {
        return this.channel.isActive();
    }

    @Override
    public ChannelExchange bind() {
        this.setAttribute(Exchange.KEY, this);
        return this;
    }

    @Override
    public SocketAddress localAddress() {
        return this.channel.localAddress();
    }

    @Override
    public SocketAddress remoteAddress() {
        return this.channel.remoteAddress();
    }
}
